package ssh

import (
	"fmt"
	"github.com/pkg/sftp"
	"golang.org/x/crypto/ssh"
	"kubeInstall/pkg/logger"
	"path"
	"strconv"
	"strings"
	"time"
)

type SSH struct {
	User     string
	Password string
	HostIp   string
	Port     int
	PkFile   string
	Timeout  *time.Duration

	SshClient  *ssh.Client
	SftpClient *sftp.Client
}

func (ss *SSH) IsFilExist(remoteFilePath string) bool {
	remoteFileName := path.Base(remoteFilePath) // aa
	remoteFileDirName := path.Dir(remoteFilePath)
	remoteFileCommand := fmt.Sprintf("ls -l %s/%s 2>/dev/null |wc -l", remoteFileDirName, remoteFileName)

	data, _ := ss.CmdToString(remoteFileCommand, " ")
	count, err := strconv.Atoi(strings.TrimSpace(data))
	defer func() {
		if r := recover(); r != nil {
			logger.Error("[ssh][%s]RemoteFilExist:%s", ss.HostIp, err)
		}
	}()
	if err != nil {
		panic(1)
	}
	if count == 0 {
		return false
	} else {
		return true
	}
}

func (ss *SSH) IsDirExist(dirName string) bool {
	remoteFileDirName := path.Dir(dirName)
	remoteFileCommand := fmt.Sprintf("ls -l %s 2>/dev/null |wc -l", remoteFileDirName)

	data, _ := ss.CmdToString(remoteFileCommand, " ")
	count, err := strconv.Atoi(strings.TrimSpace(data))
	defer func() {
		if r := recover(); r != nil {
			logger.Error("[ssh][%s]RemoteFilExist:%s", ss.HostIp, err)
		}
	}()
	if err != nil {
		panic(1)
	}
	if count == 0 {
		return false
	} else {
		return true
	}
}

//Cmd is in host exec cmd
func (ss *SSH) CmdWithStatus(cmd string) ([]byte, error) {
	logger.Info("[ssh][%s]exec cmd is : \n %s", ss.HostIp, cmd)
	session, err := ss.NewSession()
	defer func() {
		if r := recover(); r != nil {
			logger.Error("[ssh][%s]Error create ssh session failed: %s", ss.HostIp, err)
		}
	}()
	if err != nil {
		panic(1)
	}
	defer session.Close()

	b, err := session.CombinedOutput(cmd)
	if err != nil {
		logger.Error("[ssh][%s]Error exec command failed: %s", ss.HostIp, err)
		return nil, err
	}
	logger.Debug("[ssh][%s]command result is: \n %s", ss.HostIp, string(b))

	return b, err
}

//CmdToString is in host exec cmd and replace to spilt str
func (ss *SSH) CmdToString(cmd, spilt string) (string, error) {
	data, err := ss.CmdWithStatus(cmd)
	if err != nil {
		return "", err
	}
	if data != nil {
		str := string(data)
		str = strings.ReplaceAll(str, "\r\n", spilt)
		return str, nil
	}
	return "", nil
}
